package com.woniu.controller;

import cn.dev33.satoken.util.SaResult;
import com.woniu.annotation.OperateLog;
import com.woniu.entity.SysOperateLog;
import com.woniu.service.SysOperateLogService;
import jakarta.annotation.Resource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author pml
 * @Date 2025/6/19 23:29
 * @Description TODO
 * @Description 操作日志控制器
 * 处理与系统操作日志相关的HTTP请求
 * 所有接口需要登录验证，使用@SaCheckLogin注解
 * @Date 2025/6/19 15:21
 */
@RestController
@RequestMapping("sysOperateLog")
public class SysOperateLogController {

    /**
     * 注入Service而非直接注入Mapper，符合分层架构
     * Controller层只处理HTTP请求和响应，不包含业务逻辑
     */
    @Resource
    private SysOperateLogService sysOperateLogService;

    /**
     * 添加操作日志
     * 系统自动记录用户操作时调用此接口
     * 创建时间设为当前时间，创建人默认为system
     * @param sysOperateLog 操作日志信息
     * @return 操作结果
     */
    @PostMapping("/add")
    public SaResult add(@RequestBody SysOperateLog sysOperateLog) {
        sysOperateLog.setCreateTime(LocalDateTime.now());
        sysOperateLog.setCreator("system"); // 系统自动创建的日志，创建人固定为system
        return SaResult.ok().setData(sysOperateLogService.save(sysOperateLog));
    }

    /**
     * 删除操作日志
     * 提供按ID删除单条日志的功能
     * 操作日志通常用于审计，一般不删除，此处保留接口用于特殊情况
     * @param id 日志ID
     * @return 操作结果
     */
    @DeleteMapping("/delete/{id}")
    public SaResult delete(@PathVariable Integer id) {
        return SaResult.ok().setData(sysOperateLogService.removeById(id));
    }

    /**
     * 修改操作日志
     * 日志通常不需要修改，此接口用于特殊情况（如补充备注信息）
     * 更新时自动设置更新时间
     * @param sysOperateLog 操作日志信息
     * @return 操作结果
     */
    @PutMapping("/update")
    public SaResult update(@RequestBody SysOperateLog sysOperateLog) {
        sysOperateLog.setUpdateTime(LocalDateTime.now());
        return SaResult.ok().setData(sysOperateLogService.updateById(sysOperateLog));
    }

    /**
     * 根据ID查询操作日志
     * 用于查看单条日志的详细信息，包括请求参数和返回结果
     * @param id 日志ID
     * @return 日志详情
     */
    @GetMapping("/get/{id}")
    public SaResult getById(@PathVariable Integer id) {
        return SaResult.ok().setData(sysOperateLogService.getById(id));
    }

    /**
     * 查询所有操作日志
     * 添加操作日志注解，记录管理员的查询行为
     * @return 日志列表
     */
//    @OperateLog(module = "operateLog", operateType = "query", content = "查询所有操作日志列表")
    @GetMapping("/list")
    public SaResult list() {
        return SaResult.ok().setData(sysOperateLogService.list());
    }

    /**
     * 根据用户ID查询操作日志
     * 管理员需要查看特定用户的操作历史，用于审计和问题排查
     * @param userId 用户ID
     * @return 该用户的操作日志列表
     */
    @GetMapping("/listByUserId/{userId}")
    public SaResult listByUserId(@PathVariable Integer userId) {
        List<SysOperateLog> logs = sysOperateLogService.listByUserId(userId);
        return SaResult.ok().setData(logs);
    }

    /**
     * 根据模块查询操作日志
     * 按模块分类查看操作，便于系统维护和问题定位
     * @param module 模块名称
     * @return 该模块的操作日志列表
     */
    @GetMapping("/listByModule/{module}")
    public SaResult listByModule(@PathVariable String module) {
        List<SysOperateLog> logs = sysOperateLogService.listByModule(module);
        return SaResult.ok().setData(logs);
    }

    /**
     * 根据时间范围查询操作日志
     * 支持按时间段筛选日志，用于生成操作报表
     * 使用@DateTimeFormat注解解析前端传递的日期时间参数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 时间范围内的操作日志列表
     */
    @GetMapping("/listByTimeRange")
    public SaResult listByTimeRange(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        List<SysOperateLog> logs = sysOperateLogService.listByTimeRange(startTime, endTime);
        return SaResult.ok().setData(logs);
    }

    /**
     * 清理过期操作日志
     * 提供按天数清理历史日志的功能，防止表数据过大影响性能
     * 添加操作日志注解，记录此敏感操作
     * @param days 保留最近天数
     * @return 清理结果
     */
    @OperateLog(module = "operateLog", operateType = "delete", content = "清理过期操作日志")
    @DeleteMapping("/cleanExpiredLogs/{days}")
    public SaResult cleanExpiredLogs(@PathVariable int days) {
        int count = sysOperateLogService.cleanExpiredLogs(days);
        return SaResult.ok().setMsg("成功清理" + count + "条过期日志");
    }
}